package com.dbh.company.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.UUID;
import com.alibaba.fastjson.JSONObject;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.HttpMethod;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import org.apache.http.entity.ContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author dongbanghui
 * @create 2023/9/12
 */
public class S3Util2 {

    private static final Logger LOGGER = LoggerFactory.getLogger(S3Util2.class);

    private static String endpoint = "http://storage.lianjia.com";

    private static String ak = "TX6OAEXN6Q9GO83J88TI";
    private static String sk = "t4iN+BvuX4Bz69M0VxC7SjIPuq/6nOfhh/toMUgj";

    public static String generateUrl(String bucket, String key) {
        AwsClientBuilder.EndpointConfiguration endpointConfiguration =
                new AwsClientBuilder.EndpointConfiguration(endpoint, "cn-north-1");//只有外网才有预签名
        BasicAWSCredentials awsCreds = new BasicAWSCredentials(ak, sk);
        AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                .withEndpointConfiguration(endpointConfiguration)
                .withPathStyleAccessEnabled(true)
                .build();
        // Set the presigned URL to expire after one hour.
        Date expiration = new Date();
        long expTimeMillis = expiration.getTime();
        expTimeMillis += 1000 * 60 * 60 * 24 * 7;
        expiration.setTime(expTimeMillis);

        // Generate the presigned URL.
        System.out.println("Generating pre-signed URL.");
        GeneratePresignedUrlRequest generatePresignedUrlRequest =
                new GeneratePresignedUrlRequest(bucket, key)
                        .withMethod(HttpMethod.GET)
                        .withExpiration(expiration);
        generatePresignedUrlRequest.withSdkRequestTimeout(1000);

        generatePresignedUrlRequest.withSdkClientExecutionTimeout(1000);
        URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
        S3Object object = s3Client.getObject(bucket, key);
        System.out.println("-------"+ JSONObject.toJSON(object));
        int t1 = generatePresignedUrlRequest.getSdkRequestTimeout();
        int t2 = generatePresignedUrlRequest.getSdkClientExecutionTimeout();
        System.out.println(t1+"  "+t2);
        String returnUrl = url.toString();
        return returnUrl;
    }

    public static void upload(String bucket, String key, byte[] buffer, String contentType) {
        AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endpoint, "cn-north-1");

        try {
            BasicAWSCredentials awsCreds = new BasicAWSCredentials(ak, sk);

            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withPathStyleAccessEnabled(true)
                    .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                    .withEndpointConfiguration(endpointConfiguration)
                    .build();

            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType(contentType);//文件的content-type
            metadata.setContentLength(buffer.length);
            InputStream is = new ByteArrayInputStream(buffer);

            PutObjectRequest request = new PutObjectRequest(bucket, key, is, metadata);

            request.setMetadata(metadata);
            PutObjectResult putObjectResult = s3Client.putObject(request);
           Console.log("上传成功,bucket--{}, key:{}", bucket, key);
//            GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest(bucket, key);
//            URL url = s3Client.generatePresignedUrl(urlRequest);
//            System.out.println(url.toString());
        } catch (AmazonServiceException e) {
            e.printStackTrace();
        } catch (SdkClientException e) {
            e.printStackTrace();
        }
    }

    public static String upload(String bucket, String key, String filePath, String contentType) {
        AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endpoint, "cn-north-1");

        try {
            BasicAWSCredentials awsCreds = new BasicAWSCredentials(ak, sk);

            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withPathStyleAccessEnabled(true)
                    .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                    .withEndpointConfiguration(endpointConfiguration)
                    .build();

            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType(contentType);//文件的content-type
            PutObjectRequest request = new PutObjectRequest(bucket, key, new File(filePath));
            request.setMetadata(metadata);
            s3Client.putObject(request);
            Console.log(key);
            return key;
//            GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest(bucket, key);
//            URL url = s3Client.generatePresignedUrl(urlRequest);
//            System.out.println(url.toString());
        } catch (AmazonServiceException e) {
            e.printStackTrace();
        } catch (SdkClientException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * s3删除文件
     * @param bucketName
     * @param key
     */
    public static void delete(String bucketName, String key) {
        AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endpoint, "cn-north-1");
        try {
            BasicAWSCredentials awsCreeds = new BasicAWSCredentials(ak, sk);
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withPathStyleAccessEnabled(true)
                    .withCredentials(new AWSStaticCredentialsProvider(awsCreeds))
                    .withEndpointConfiguration(endpointConfiguration)
                    .build();
            s3Client.deleteObject(bucketName, key);
            Console.log("数据已物理删除,结果成功,bucket:{}, key:{}", bucketName, key);

        } catch (AmazonServiceException e) {
            LOGGER.error("AmazonServiceException : ", e);
        } catch (SdkClientException e) {
            LOGGER.error("SdkClientException : ", e);
        }
    }

    public static String uploadLargeFile(String bucketName, String key, File file, String contentType) {
        AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endpoint, "cn-north-1");
        BasicAWSCredentials awsCreds = new BasicAWSCredentials(ak, sk);

        AmazonS3 amazonS3 = AmazonS3ClientBuilder.standard()
                .withPathStyleAccessEnabled(true)
                .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
                .withEndpointConfiguration(endpointConfiguration)
                .build();

        int partSize = 10 * 1024 * 1024; // 分片大小（10MB）

        // 创建InitiateMultipartUploadRequest对象
        InitiateMultipartUploadRequest initRequest = new InitiateMultipartUploadRequest(bucketName, key);

        // 初始化分片上传
        InitiateMultipartUploadResult initResult = amazonS3.initiateMultipartUpload(initRequest);
        String uploadId = initResult.getUploadId();

        try {
            // 读取文件
            long contentLength = file.length();

            // 计算分片数量
            int partCount = (int) Math.ceil((double) contentLength / partSize);
            System.out.println("总分片-->" + partCount);

            // 创建分片上传请求列表
            List<PartETag> partETags = new ArrayList<>();

            // 分片上传
            for (int i = 0; i < partCount; i++) {
                // 计算分片的起始位置和结束位置
                long start = (long) i * partSize;
                long end = Math.min(start + partSize, contentLength) - 1;

                // 创建UploadPartRequest对象
                UploadPartRequest uploadRequest = new UploadPartRequest()
                        .withBucketName(bucketName)
                        .withKey(key)
                        .withUploadId(uploadId)
                        .withPartNumber(i + 1)
                        .withFile(file)
                        .withFileOffset(start)
                        .withPartSize(end - start + 1);

                // 设置ContentType
                ObjectMetadata metadata = new ObjectMetadata();
                metadata.setContentType(contentType);
                uploadRequest.setObjectMetadata(metadata);

                // 上传分片
                UploadPartResult uploadResult = amazonS3.uploadPart(uploadRequest);
                partETags.add(uploadResult.getPartETag());
                System.out.println("已上传-->" + i);
            }

            // 完成分片上传
            CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest(bucketName, key, uploadId, partETags);
            amazonS3.completeMultipartUpload(completeRequest);

            LOGGER.info("文件上传成功,bucketName:{},key:{}", bucketName, key);
        } catch (Exception e) {
            // 取消分片上传
            AbortMultipartUploadRequest abortRequest = new AbortMultipartUploadRequest(bucketName, key, uploadId);
            amazonS3.abortMultipartUpload(abortRequest);
            LOGGER.error("文件上传失败：{}", e.getMessage());
        }
        return key;
    }




    public static void main(String[] args) throws MalformedURLException {

//        String key = upload("twin-model", UUID.randomUUID().toString().replace("-", "")+".insp", "D:\\data0\\滨河花苑一期-素材.insp", "image/insp");
//        System.out.println(key);
//        String key = uploadLargeFile("bh-mark", UUID.randomUUID() + ".zip",
//                new File("D:\\data\\Documents\\WXWork\\1688849989768054\\Cache\\File\\2024-09\\OSGB_small.zip"), "application/x-zip-compressed");
//        System.out.println(key);

        String s = generateUrl("bh-mark", "prod-30c2cdac-e5ad-4303-ba14-7718ee24d401.json");
        System.out.println(s);


    }

}
